home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekikoh Dennoh Club 2
/
Gekikoh Dennoh Club Vol. 2 (Japan).7z
/
Gekikoh Dennoh Club Vol. 2 (Japan) (Track 01).bin
/
tools
/
8adp
/
8adpcm.c
< prev
next >
Wrap
Text File
|
1997-10-13
|
3KB
|
183 lines
#include <stdio.h>
#include <stdlib.h>
#define UNchar unsigned char
#define UNshort unsigned short
#define UNint unsigned int
#define UNlong unsigned long
void PCM2AP8_INIT();
void AP82PCM_INIT();
UNlong PCM2AP8( short*,UNchar*,UNlong );
UNlong AP82PCM( UNchar*,short*,UNlong );
inline UNchar PCM2AP8_SUB( long );
inline short AP82PCM_SUB(UNchar );
static long P2A_lxn1,P2A_rxn1;
static long P2A_ldln,P2A_rdln;
static long A2P_lxn1,A2P_rxn1;
static long A2P_ldln,A2P_rdln;
static long f[7+1]={57,57,57,57,77,102,128,153};
static long xn1;
static long dln;
#define dsc (256)
#define lw (128*dsc)
#define lk (64*dsc)
#define dmin (127*dsc)
#define dmax (24576*dsc)
/*==============================================================*/
void PCM2AP8_INIT()
{
P2A_lxn1=0;
P2A_rxn1=0;
P2A_ldln=dmin;
P2A_rdln=dmin;
}
/*+++++++++*/
UNlong PCM2AP8(pbuff,abuff,ll)
short* pbuff;
UNchar* abuff;
UNlong ll; /// byte 数
{
long xn;
UNlong l_=ll;
ll/=4;
for(;ll>0;ll--){
//=== LEFT
xn=(long)(short)*pbuff++;
xn1 = P2A_lxn1;
dln = P2A_ldln;
*abuff++=PCM2AP8_SUB(xn);
P2A_lxn1 = xn1;
P2A_ldln = dln;
//=== RIGHT
xn=(long)(short)*pbuff++;
xn1=P2A_rxn1;
dln=P2A_rdln;
*abuff++=PCM2AP8_SUB(xn);
P2A_rxn1=xn1;
P2A_rdln=dln;
}
return(l_/2);
}
/*+++++*/
inline UNchar PCM2AP8_SUB(long xn)
{
UNchar adp;
long dn;
long oxn;
long la;
long ld;
do {
dn=xn-xn1;
la=abs(dn)*lk/dln;
if ( la>127 ) {
la=127;
/* adp …adpcmデータ*/
}
if ( dn>=0 ) {
adp=la;
ld=((la*2+1)*dln)/lw;
}
else {
adp=(la | 128);
ld=-((la*2+1)*dln)/lw;
}
oxn=xn;
/* 実際に展開して同値になるまでループ*/
xn=xn1+ld;
if ( xn>32767 )
xn=32767;
if ( xn<-32768 )
xn=-32768;
} while (!(xn==oxn));
/* 予測値(xn1)・量子化幅(dln)の更新*/
xn1=xn+ld;
dln=(f[la/16]*dln)/64;
if ( dln<dmin )
dln=dmin;
if ( dln>dmax )
dln=dmax;
return(adp);
}
/*==============================================================*/
void AP82PCM_INIT()
{
int i;
A2P_lxn1=0;
A2P_rxn1=0;
A2P_ldln=dmin;
A2P_rdln=dmin;
}
/*+++++++++*/
UNlong AP82PCM(abuff,pbuff,ll)
UNchar* abuff;
short* pbuff;
UNlong ll; // byte 数
{
int adp;
short c;
UNlong l_=ll;
ll/=2;
for(;ll>0;ll--){
//=== LEFT
adp=*abuff++;
xn1 = A2P_lxn1;
dln = A2P_ldln;
*pbuff++=AP82PCM_SUB(adp);
A2P_lxn1 = xn1;
A2P_ldln = dln;
//=== RIGHT
adp=*abuff++;
xn1 = A2P_rxn1;
dln = A2P_rdln;
*pbuff++=AP82PCM_SUB(adp);
A2P_rxn1 = xn1;
A2P_rdln = dln;
}
return(l_*2);
}
/*++++++++++++++++++++++*/
inline short AP82PCM_SUB(UNchar adp)
{
long xn;
long ld;
UNchar la;
if ( adp>127 ) {
la=adp-128;
ld=-((la*2+1)*dln)/lw;
}
else {
la=adp;
ld=((la*2+1)*dln)/lw;
}
xn=xn1+ld;
if ( xn>32767 ) {
xn=32767;
}
if ( xn<-32768 ) {
xn=-32768;
}
/* 予測値(xn1)・量子化幅(dln)の更新*/
xn1=xn+ld;
/* ←ここ変更!!!*/
dln=(f[la/16]*dln)/64;
/* ←ここ変更!!!*/
if ( dln<dmin ) {
dln=dmin;
}
if ( dln>dmax ) {
dln=dmax;
}
return(xn);
}